package org.googlecode.gwt.wii.memory.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.Widget;

public class MemoryGame extends Composite implements TableListener {
	
	final Grid gridMemory = new Grid();

	boolean interactive = true;
	
	/**
	 * @gwt.args <org.googlecode.gwt.wii.memory.client.MemoryGame.RowCell>
	 */
	List clickedCell = new ArrayList(2);
	
	private final int size;
	private final int rows;
	private final int columns;
	
	private int matched = 0;

	/**
	 * @wbp.parser.constructor
	*/	
	public MemoryGame() {
		this(8,4,4);
	}
	
	public MemoryGame(int size, int rows, int columns) {
		
		if( rows*columns != size*2) {
			throw new IllegalArgumentException("Wrong input parameter, cannot render a MemoryGame");
		}
		
		this.size = size;
		this.rows = rows;
		this.columns = columns;
		
		initWidget(gridMemory);
	}
	
	public void onLoad() {
		
		gridMemory.setSize("463px", "325px");
		gridMemory.resize(rows, columns);

		populateGrid();
		
		gridMemory.addTableListener(this);
	}

	private void populateGrid() {
		List tiles = new ArrayList(size*2);
		for(int i=0;i<size;i++) {
			tiles.add(new Integer(i));
			tiles.add(new Integer(i));
		}
		
		for(int row=0;row<rows;row++) {
			for(int cell=0;cell<columns;cell++){
				int index = (int) (Math.random()*tiles.size());
				int tile = ((Integer)tiles.get(index)).intValue();
				tiles.remove(index);
				
				Tessera tessera = new Tessera(tile);
				gridMemory.setWidget(row, cell, tessera);
			}
		}
	}

	protected void onUnload() {
		gridMemory.removeTableListener(this);
	}

	public void onClick(Widget sender) {
		if( sender instanceof Tessera ){
			Tessera tessera = (Tessera) sender;
			if( tessera.flip() ){
				clickedCell.remove(tessera);				
			}
			else {
				clickedCell.add(tessera);				
			}
		}
		
		if( clickedCell.size() == 2 ) {
			checkForMatch();

			if( matched == size ) {
				Window.alert("Hai vinto !!!");
				reset();
			}			
		}
	}

	public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
		if( interactive ){
			onClick(gridMemory.getWidget(row, cell));
		}
	}

	public void reset() {
		populateGrid();
		
		matched = 0;
		clickedCell.clear();
	}

	private void checkForMatch() {

		final Tessera tesseraA = (Tessera) clickedCell.get(0);			
		final Tessera tesseraB = (Tessera) clickedCell.get(1);
		
		if(tesseraA.getImageNumber() == tesseraB.getImageNumber()) {
			tesseraA.freeze();
			tesseraB.freeze();
			matched++;
		}
		else {
			interactive = false;
			new Timer() {

				public void run() {

					tesseraA.flip();
					tesseraB.flip();
					
					interactive = true;
				}
				
			}.schedule(2000);
			
		}
		
		clickedCell.clear();					
	}
}
